"""
    @author:sirius
    @time:2018.4.20
"""
import common.handle_file as hf
import common.scrapy
from math import log
import pandas as pd
import datetime
import math
import json


# 读取文件，读取以行为单位，每一行是列表里的一个元素
def read_file(filename):
    csv_file = pd.read_csv(filename, sep=',')
    return csv_file


# 获取事件的列表
def get_event_list(filename, user_id):
    contents = read_file(filename)
    apps_info = []
    contents = contents[contents['userid'] == user_id]
    contents = contents.loc[:, 'name']

    for content in contents:
        apps_info.append(content)

    return apps_info


# 获取事件及时间戳的列表
def get_event_timestamp_list(filename, user_id):
    contents = read_file(filename)
    contents = contents[contents['userid'] == user_id]
    if 'ResultData.csv' in filename:
        contents = contents.loc[:, ['name', 'time_x', 'location', 'speed_split']]
    else:
        contents = contents.loc[:, ['name', 'time']]

    apps_info = contents.values.tolist()

    return apps_info


# 获取事件的列表-UserBased (app_sys_tmp.csv)
def get_event_list_by_period(PERIOD_FEATURE, filename, user_id):
    global date_dict
    date_list = []

    contents = read_file(filename)
    apps_info = {}
    contents = contents[contents['userid'] == user_id]
    if not contents.empty:
        for timestamp, db_key in zip(contents['time'], contents['db_key']):
            date_dict = {'userid': user_id, 'db_key': db_key}
            date_dict = format_time(date_dict, timestamp)
            date_list.append(date_dict)

        date_dt = pd.DataFrame(date_list)

        # 工作日和假期的区分
        date_dt.loc[date_dt['week'] == 'Mon', 'week'] = 'workday'
        date_dt.loc[date_dt['week'] == 'Tue', 'week'] = 'workday'
        date_dt.loc[date_dt['week'] == 'Wed', 'week'] = 'workday'
        date_dt.loc[date_dt['week'] == 'Thu', 'week'] = 'workday'
        date_dt.loc[date_dt['week'] == 'Fri', 'week'] = 'workday'
        date_dt.loc[date_dt['week'] == 'Sat', 'week'] = 'holiday'
        date_dt.loc[date_dt['week'] == 'Sun', 'week'] = 'holiday'

        contents = pd.merge(contents, date_dt, how='left', on='db_key')
        contents = contents[contents['date'].str.contains(pattern_month_date(PERIOD_FEATURE['date']))]
        contents = contents[contents.period.isin([PERIOD_FEATURE['period']])]

        contents = contents.loc[:, 'name']

        for content in contents:
            if content in apps_info.keys():
                apps_info[content] += 1 / len(contents)
            else:
                apps_info[content] = 1 / len(contents)

    return apps_info


# 获取事件的列表-ItemBased (app_rec_gps_tmp.csv)
def get_apps_click_by_period(PERIOD_FEATURE, filename, item):
    global date_dict
    date_list = []

    contents = read_file(filename)
    apps_info = {}

    if not contents.empty:
        contents = contents[contents['date'].str.contains(pattern_month_date(PERIOD_FEATURE['date']))]
        contents = contents[contents.period.isin([PERIOD_FEATURE['period']])]
        all_num = len(contents)
        contents = contents[contents['name'] == item]
        item_num = len(contents)

        apps_info[item] = item_num / all_num

    return apps_info


# 获取应用-事件ID的列表
def get_app_list(filename):
    contents = read_file(filename)
    apps_info = {}
    key_list = contents.loc[:, 'db_key']
    name_list = contents.loc[:, 'name']

    for key, name in zip(key_list, name_list):
        apps_info[name] = key

    return apps_info


# 格式化时间
def format_time(date_dict, time):
    # 取日期
    dt = datetime.datetime.utcfromtimestamp(time)
    date = dt.strftime('%Y-%m-%d')
    date_dict['date'] = date

    # 取星期
    date_dict['week'] = dt.strftime('%a')

    # 取月份
    date_dict['month'] = dt.strftime('%b')

    # 取时间点
    # d = datetime.datetime(dt.year, dt.month, dt.day, 2)
    if datetime.datetime(dt.year, dt.month, dt.day, 0) < dt < datetime.datetime(dt.year, dt.month, dt.day, 7):
        date_dict['period'] = 'Night'
    elif dt < datetime.datetime(dt.year, dt.month, dt.day, 11):
        date_dict['period'] = 'Morning'
    elif dt < datetime.datetime(dt.year, dt.month, dt.day, 14):
        date_dict['period'] = 'Noon'
    elif dt < datetime.datetime(dt.year, dt.month, dt.day, 18):
        date_dict['period'] = 'Afternoon'
    elif dt < datetime.datetime(dt.year, dt.month, dt.day, 23, 59, 59):
        date_dict['period'] = 'Evening'

    return date_dict


# 时间月份日匹配模式
def pattern_month_date(datetime):
    return r'[0-9]*' + datetime[4:]


# 计算权重
def weight_cal(click_dict, down_app, file_name):
    # print 'down_app:', self.down_app
    # 各用户app使用权重字典
    u_weight = {}
    # print 'click_dict',self.click_dict
    for user in click_dict:
        # app使用流行度字典
        up = {}
        # Android市场流行度字典
        iw = {}
        # 流行度最大值索引
        index_use = max(click_dict[user], key=click_dict[user].get)
        index_market = max(down_app[user], key=down_app[user].get)
        for i in click_dict[user]:
            up[i] = click_dict[user][i] / click_dict[user][index_use]
            iw[i] = log(down_app[user][index_market] / common.scrapy.spider(i))
            # print self.down_app[user][index_market], scrapy.spider(i)
            try:
                u_weight[user][i] = up[i] * iw[i]
            except Exception as e:
                u_weight[user] = {i: up[i] * iw[i]}

    hf.write_file(str(u_weight), file_name, 'Weight')
    print('周期律权重：', u_weight)


# 预测命中概率权重至计算
def cal_pr_weight(weight):
    weight = math.pow(weight, 2) ** 0.5
    return weight


# 判断两个字典是否相等
def dicts_equal(dict1, dict2):
    if dict1.keys() == dict2.keys():
        for item1 in dict1:
            for item2 in dict2:
                if item1 == item2:
                    if dict1[item1] == dict2[item2]:
                        return True
                    else:
                        return False
                    break
    else:
        return False


# 格式化frozenset
def format_frozenset(frozen_set):
    if type(frozen_set) == frozenset:
        frozenset_str = str(frozen_set)
        return frozenset_str[frozenset_str.index("'") + 1:frozenset_str.rindex("'")]
    else:
        return frozen_set

# 判断是否包含内嵌列表
def lol_contain(nest_list, element):
    index_of_list = 0
    for inside_list in nest_list:
        if element in inside_list:
            return True, index_of_list
        index_of_list += 1

    return False, 0


# 判断是否包含内嵌列表
def lol_contain_app(nest_list, element):
    for inside_list in nest_list:
        if element[0] in inside_list[0]:
            return True, 83.2342357834767743595, 100

    return False, 83.2342357834767743595, 100


# 持久化存储应用信息数据
def save_app_data(info_str):
    isTrue = False
    if info_str:
        info_obj = json.loads(info_str)

        apps = info_obj['apps']
        batteries = info_obj['batteries']
        networks = info_obj['networks']

        for app, battery, network in zip(apps, batteries, networks):
            hf.write_file_add(app + ',' + str(battery) + ',' + str(network) + '\n', '../cache/AppInfo.txt', 'AppInfo')
        isTrue = True

    return isTrue


if __name__ == '__main__':
    info_str = '{"apps":["phone","wechat"],"batteries":[1,2,3],"networks":[3,1,2]}'

    save_app_data(info_str)
